package CommunicationTest;
/*
线程通信应用：生产者/消费者问题
生产者（producer）将产品交给店员（Clerk），消费者(Consumer)从店员处取走产品，店员一次只能持有一定数量的产品（例如：10个），若生产者视图
生产更多的产品，店员会叫生产者暂停一下，若若店员处有空位在通知生产者生产；若店员中没有产品了会告诉消费者等待一下，有产品了再通知
消费者取走产品
*/
class Clerk{
    private int productNum=0;
    public synchronized void produce() {
        if (productNum<10){
            productNum++;
            System.out.println(Thread.currentThread().getName()+"正在生产第"+productNum+"个产品");
            notify();//当生产者生产出一个产品时就通知消费者消费
        }else {
            try {
                wait();//超过一定数量就阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void consume() {
        if (productNum>0){
            System.out.println(Thread.currentThread().getName()+"正在消费第"+productNum+"个产品");
            productNum--;
            notify();//当消费者者生消费一个产品时就通知生产者生产
        }else {
            try {
                wait();//超过一定数量就阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
class Producer implements Runnable{
    private Clerk clerk;

    public Producer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println("产品正在生产....");
        while (true){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.produce();
        }
    }
}
class Consumer implements Runnable{
    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println("产品正在消费....");
        while (true){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.consume();
        }
    }
}


public class Communication {
    public static void main(String[] args) {
        Clerk clerk=new Clerk();
        Producer producer=new Producer(clerk);
        Thread pro1=new Thread(producer);
        pro1.setName("生产者1");
        pro1.start();
        Consumer consumer=new Consumer(clerk);
        Thread con1=new Thread(consumer);
        Thread con2=new Thread(consumer);
        con1.setName("消费者1");
        con2.setName("消费者2");
        con1.start();
        con2.start();

    }
}
